home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
dpmigcc5.zip
/
RSX
/
SOURCE
/
RSX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-12
|
10KB
|
440 lines
/*****************************************************************************
* FILE: rsx.c *
* *
* DESC: *
* - get rsx options *
* - switch protected mode (16bit) *
* - init protected mode *
* - check copro, install emu *
* - load first a.out prg *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: rainer@mathematik.uni-bielefeld.de *
* *
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "DPMI.H"
#include "PRINTF.H"
#include "PROCESS.H"
#include "START32.H"
#include "LOADPRG.H"
#include "FPU.H"
#include "RSX.H"
#include "DOSERRNO.H"
#include "RMLIB.H"
#include "COPY32.H"
#include "SYSDEP.H"
#include "DJIO.H"
#include "VERSION.H"
/* command-line options */
char copro = 1; /* prg need 387 : 0=no 1=yes 3=emulate */
char opt_memaccess = 0; /* allows memaccess */
char opt_stack = 0; /* stack: expand down or data segment */
char rsx387_in_dosmem = 1; /* rsx387 in dos memory (not rsx32) */
char opt_force_dpmi09 = 1; /* force only DPMI 0.9 calls */
char opt_version = 0; /* print rsx version */
char opt_force_copro; /* force copro status */
int opt_stackval = 0; /* stack size in KB */
int opt_max_dos_handles; /* DOS handles for RSX */
char opt_nocore; /* don't write core file */
char opt_schedule; /* enable schedule() */
int opt_memalloc = 0; /* pre-alloc heap */
char opt_zero = 0; /* zero heap */
char opt_os2 = 0; /* set os/2 bit */
/* special test options */
char opt_kdeb; /* Kernel debug mode */
char opt_printall = 0; /* show all information (testing RSX) */
char opt_print_syscalls = 0; /* show every sys_call (testing RSX) */
char opt_redir; /* redirect handle 1 (testing RSX) */
char opt_debugrsx; /* debug rsx; don't set int3 */
/* other globals */
char npx_present; /* npx present 1/0 */
char kdeb_program[80]; /* program for kernel debug mode */
int rsx_stdout = 1;
int kread; /* keyboard read */
int kready; /* keyboard check */
unsigned bios_selector; /* selector bios area */
char **org_env; /* org. environment to rsx */
int org_envc; /* org. env items */
static int emxl_psp = 0; /* exe-stub emxl.exe psp */
int hexstr2int(char *s)
{
int i, res=0;
for (i = 0; i < 4; i++) {
char c = s[i];
if (c >= 'a')
c -= ('a' - 10);
else if (c >= 'A')
c -= ('A' - 10);
else
c -= '0';
res <<= 4;
res |= c;
}
return res;
}
/* return first non-digit */
static char * asc2int(char *s, int *retv)
{
char *str = s;
*retv = 0;
while (*str != 0) {
if ((*str < '0') || (*str > '9'))
break;
*retv *= 10;
*retv += *str - '0';
str++;
}
return (str);
}
/*
** get one options for rsx
** return last char pos, if successful
*/
char *scan_for_option(char *s, NEWPROCESS *p)
{
int temp;
char *t;
switch (*s) {
/*
** emx options with emxbind:
** -a*, -c, -f#, -h#, -p, -s#, -C#, -L
*/
case 'a': /* DOS features */
for (++s; *s > ' '; ++s) {
if (*s == 'm') {
if (p)
p->options |= OPT_MEMACCESS;
else
opt_memaccess = 1;
}
else if (*s == 'c' || *s == 'i' || *s == 'w')
continue;
else
return NULL;
}
if (*(--s) == 'a')
return NULL;
break;
case 'c': /* core */
opt_nocore = 1;
break;
case 'e': /* changed !! */
puts("-e option for copro has changed to -Re");
return NULL;
case 'f': /* frame size (ignore) */
case 's': /* stack size (ignore) */
case 'C': /* commit */
while (isdigit(*++s))
;
--s;
break;
case 'h': /* max handles */
++s;
if (!isdigit(*s))
return NULL;
t = asc2int(s, &temp);
if (p && temp > opt_max_dos_handles)
rm_sethandles(temp);
opt_max_dos_handles = temp;
return t;
case 'p': /* don't use lower DOS mem */
rsx387_in_dosmem = 0;
break;
case 'R': /* special RSX options */
for (++s; *s > ' '; ++s) {
if (*s == ',')
++s;
switch (*s) {
case 'a': /* ss = ds */
opt_stack = 1;
break;
case 'e': /* copro */
copro = 0;
if (isdigit(*(s+1)))
opt_force_copro = *(++s) - '0' + 1;
break;
case 'm': /* malloc for memaccess */
if (!isdigit(*(s+1)))
break;
s = asc2int(++s, &opt_memalloc) - 1;
break;
case 's': /* stack frame */
++s;
if (!isdigit(*s))
return NULL;
return asc2int(s, &opt_stackval);
case 'x': /* enable schedule */
opt_schedule = 1;
break;
case 'z': /* zero heap */
opt_zero = 1;
break;
case '1': /* no dpmi10 calls */
opt_force_dpmi09 = 0;
break;
case '9': /* no dpmi10 calls */
opt_force_dpmi09 = 1;
break;
case 'D': /* don't touch int3 */
opt_debugrsx = 1;
break;
case 'F': /* redirect output */
opt_redir = 1;
break;
case 'I': /* print syscalls */
opt_print_syscalls = 1;
break;
case 'K': /* kernel debug */
opt_kdeb = 1;
break;
case 'O': /* set OS/2 bit */
opt_os2 = 1;
break;
case 'P': /* print syscalls */
opt_printall = 1;
break;
default:
puts("unknown -Rxx option");
return NULL;
}
}
if (*(--s) == 'R')
return NULL;
break;
case 'V': /* version print */
opt_version = 1;
break;
default:
return NULL;
} /* switch (*s) */
return s;
}
static void init_bios_keyboard(void)
{
/* get DPMI selector for BIOS area, on error try 0x40 */
if (SegToSel(0x40, &bios_selector))
bios_selector = 0x40;
/* services for enhanced keyboards, otherwise older types */
if ((BYTE) read32(bios_selector, 0x96) & 0x10) {
kread = 0x10;
kready = 0x11;
} else {
kread = 0;
kready = 1;
}
/* flush input */
while (rm_bios_read_keybrd(kready))
rm_bios_read_keybrd(kread);
}
static int setup_environment(char **env)
{
char *s;
/* save environment, env-size */
for (org_envc = 0; env[org_envc] != NULL; org_envc++)
;
org_env = env;
/* get enviroment options */
s = getenv("RSXOPT");
if (s != NULL) {
for (; *s != '\0'; ++s) {
while (*s == ' ')
++s;
if (*s == '-') {
s = scan_for_option(++s, NULL);
if (s == NULL) {
puts(version);
puts("error in RSXOPT");
return (1);
}
} else
break;
}
}
return 0;
}
static int get_rsx_options(int start, char **argv)
{
int i;
char *s;
for (i = start; argv[i]; i++) {
if (argv[i][0] == '-') {
s = scan_for_option(& argv[i][1], NULL);
if (s == NULL) {
puts(version);
printf("bad option: %s\n", argv[i]);
return -1;
}
} else
break;
}
return i;
}
#ifdef __EMX__
#define exit(x) dos_exit(x)
#endif
/*
** MAIN():
** real mode for rsx16
** protected mode rsx32
*/
void main(int argc, char **argv, char **env)
{
static char exefile[128];
int file_arg, err;
#ifndef __EMX__
set_stdout();
#endif
init_real_mode();
if (setup_environment(environ))
exit(1);
/* check bound exe-file */
if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '/'
&& argv[1][6] == '/') {
emxl_psp = hexstr2int(&argv[1][2]);
get_emxl_psp(emxl_psp);
build_emx_args(&argc, &argv);
file_arg = 0;
} else if (argc > 1 && strcmp(argv[1], "!proxy") == 0) {
build_dj_args(&argc, &argv);
emxl_psp = 1;
file_arg = 0;
} else if (strcmp(argv[0], "!RSX") == 0) {
emxl_psp = 1;
file_arg = 1;
} else {
file_arg = get_rsx_options(1, argv);
if (file_arg == -1)
exit(1);
opt_version = 1;
}
/* print version, if rsx running from prompt */
if (opt_version)
puts(version);
/* check filename */
if (argc <= file_arg) {
puts("no filename defined");
exit(1);
}
/* copro required, 387 there ? */
npx_present = (char) npx_installed();
if (opt_force_copro)
copro = opt_force_copro - (char) 1;
else if (copro == 1 && !npx_present)
copro = 3;
if (real_to_protected(1))
exit(1);
/* - - - now protected mode! - - - rsx/rsx32 */
if (test_dpmi_capabilities())
protected_to_real(1);
if (hangin_extender()) {
puts("ERROR: can't hang in extensions");
protected_to_real(1);
}
if (opt_kdeb && argv[file_arg + 2])
strcpy(kdeb_program, argv[file_arg + 2]);
/* init process-tables */
init_this_process();
/* init bios_selector & get keyboard */
init_bios_keyboard();
strcpy(exefile, argv[file_arg]);
if (rm_access(exefile, 0) == -1) {
strcat(exefile, ".exe");
if (rm_access(exefile, 0) == -1) {
printf("file not found: %s\n", argv[file_arg]);
shut_down(1);
}
}
if (!opt_max_dos_handles)
opt_max_dos_handles = N_FILES;
else if (opt_max_dos_handles > RSX_NFILES)
opt_max_dos_handles = RSX_NFILES;
rm_sethandles(opt_max_dos_handles);
/* hang in emulation */
if (copro == 3)
if (install_rsx387())
shut_down(2);
init_fpu();
/* rsx output */
if (opt_redir)
if ((rsx_stdout = rm_creat("rsx.log", _A_NORMAL)) < 0)
rsx_stdout = 1;
err = exec32(P_WAIT, exefile, argc - file_arg, argv + file_arg, org_envc, org_env);
printf("%s: ", exefile);
switch (err) {
case EMX_ENOEXEC:
puts("Not a valid a.out format");
break;
case EMX_ENOMEM:
puts("Not enough DPMI memory");
break;
default:
printf("Can't load file, emx errno = %d\n", err);
break;
}
shut_down(1);
/* never reached */
}